﻿using System;
using System.Collections.Generic;
using System.Text;
using FieldDevice.ModBus;
using FieldDevice;
using FieldLib;
namespace FieldDevice.Emulation
{
    class ACR120ELEmulator : DeviceEmulator
    {
        public ACR120ELEmulator(ushort address)
            : base(address)
        {
            this.timeACR330Emulator = new System.Windows.Forms.Timer();
            this.timeACR330Emulator.Enabled = true;
            this.timeACR330Emulator.Interval = 1000;
            this.timeACR330Emulator.Tick += new EventHandler(this.timeACR330Emulator_tick);
            DataEmulator = new DataEmulatorForm(address);
            DataEmulator.Show();
        }
        DataEmulatorForm DataEmulator;
        private System.Windows.Forms.Timer timeACR330Emulator;


        public const ushort ADDR_PT = 0x0003;           //PT变比
        public const ushort ADDR_CT = 0x0004;           //CT变比
        public const ushort ADDR_DIO = 0x22;            //0x22/bit0 判断工作状态
        public const ushort ADDR_Flag_UI = 0x23;        //电流电压的小数点
        public const ushort ADDR_Flag_P = 0x24;         //电功率的小数点
        public const ushort ADDR_Va = 0x25;             //A相电压
        public const ushort ADDR_Vb = 0x26;             //B相电压 
        public const ushort ADDR_Vc = 0x27;             //C相电压
        public const ushort ADDR_Vab = 0x28;            //AB线电压
        public const ushort ADDR_Vbc = 0x29;            //BC线电压
        public const ushort ADDR_Vca = 0x2A;            //CA线电压

        public const ushort ADDR_Ia = 0x2B;             //A相电流
        public const ushort ADDR_Ib = 0x2C;             //B相电流
        public const ushort ADDR_Ic = 0x2D;             //C相电流
            
        public const ushort ADDR_P = 0x31;              //总有功功率
        public const ushort ADDR_Q = 0x35;              //总无功功率
        public const ushort ADDR_S = 0x3d;              //总视在功率

        public const ushort ADDR_F = 0x3e;              //频率
        public const ushort ADDR_PF = 0x39;             //总功率因数

        public const ushort ADDR_EPI_Hi = 0x3f;         //有功电度
        public const ushort ADDR_EPI_Low = 0x40;
        public const ushort ADDR_EPE_Hi = 0x41;        //释放有功电能（次要）
        public const ushort ADDR_EPE_Low = 0x42;
        public const ushort ADDR_EQL_Hi = 0x43;         //无功电度
        public const ushort ADDR_EQL_Low = 0x44;
        public const ushort ADDR_EQC_Hi = 0x45;         //释放无功电能（次要）
        public const ushort ADDR_EQC_Low = 0x46;

        public short Register0023=0x0202;
        public short Register0024=0x0000;
        public short Register002B_IA;
        public short Register002C_IB;
        public short Register002D_IC;
        public short Register0025_UA;
        public short Register0026_UB;
        public short Register0027_UC;
        public short Register0028_Uab;
        public short Register0029_Ubc;
        public short Register002A_Uca;
        public short Register_P;
        public short Register_Q;
        public float Register_S;
        public float Register_PF;
        public short Register_F;

        byte[] ModBuffer = new byte[1 + 2 + 2 + 256 * 2 + 2 + 2 + 1];
        int DataLen;
        public override byte[] ProcessModBusPacket(ModBusPacket packet)
        {
            ModBuffer[0] = packet.SlaveAddress;
            ModBuffer[1] = packet.Function;
            ModBusPacket tmpPacket = packet;
            tmpPacket = CRCVerify(tmpPacket);
            if (packet.CRCH != tmpPacket.CRCH || packet.CRCL != tmpPacket.CRCL)
            {
                packet.DataNumberHi = 0x00;
                packet.DataNumberLow = 0x00;
            }

            switch (packet.Function)
            {
                case ModBus.ModBusFunction.READHOLDINGREGISTER:
                                    ReadRegister(packet);
                                    break;
                default:
                                    break;
            }
            packet = CRCVerify(packet);
            ModBuffer[2 * DataLen + 3] = packet.CRCH;
            ModBuffer[2 * DataLen + 4] = packet.CRCL;
            return ModBuffer;

        }

       public void ReadRegister(ModBusPacket input)
        {
            ushort tmpAddressData;
            short tmpData;           
            tmpAddressData = input.DataAddressHi;
            tmpAddressData <<= 8;
            tmpAddressData += input.DataAddressLow;
            DataLen = input.DataNumberHi;
            DataLen <<= 8;
            DataLen += input.DataNumberLow;
            ModBuffer[2] = (byte)DataLen;
            for (int i = 0; i < DataLen; i++)
            {
                 tmpData = (short)RegisterValue(tmpAddressData + i);
                 ModBuffer[2*i + 3] = (byte)(tmpData >> 8);       
                 ModBuffer[2*i + 4] = (byte)(tmpData & 0xff);
            }
       }

       private float RegisterValue(int addr)
       {
           float value=0;
           switch (addr)
           {
               case ADDR_Ia:
                   value=Register002B_IA;
                   break;
               case ADDR_Ib:
                   value = Register002C_IB;
                   break;
               case ADDR_Ic:
                   value = Register002D_IC;
                   break;
               case ADDR_Va:
                   value = Register0025_UA;
                   break;
               case ADDR_Vb:
                   value = Register0026_UB;
                   break;
               case ADDR_Vc:
                   value = Register0027_UC;
                   break;
               default:
               
                   break;
           }
            return value;
       
       }
        private void timeACR330Emulator_tick(object sender, EventArgs e)
        {
            Random randomNum = new Random();
            this.Register002B_IA = (short)randomNum.Next(500);
            DataEmulator.IA = Convert.ToString(this.Register002B_IA);
            this.Register002C_IB = (short)randomNum.Next(500);
            DataEmulator.IB = Convert.ToString(this.Register002C_IB);
            this.Register002D_IC = (short)randomNum.Next(500);
            DataEmulator.IC = Convert.ToString(this.Register002D_IC);

            this.Register0025_UA = (short)randomNum.Next(37000,39000);
            DataEmulator.VA = Convert.ToString(this.Register0025_UA);
            this.Register0026_UB = (short)randomNum.Next(37000,39000);
            DataEmulator.VB = Convert.ToString(this.Register0026_UB);
            this.Register0027_UC = (short)randomNum.Next(37000,39000);
            DataEmulator.VC = Convert.ToString(this.Register0027_UC);
            this.Register0028_Uab = (short)randomNum.Next(37000, 39000);
            this.Register0029_Ubc = (short)randomNum.Next(37000, 39000);
            this.Register002A_Uca = (short)randomNum.Next(37000, 39000);
            this.Register_P = (short)randomNum.Next(100000, 120000);
            this.Register_Q = (short)randomNum.Next(100000, 120000);
            this.Register_S = (short)randomNum.Next(100000, 120000);
            this.Register_PF = (float)randomNum.Next(0, 1);
            this.Register_F = (short)randomNum.Next(40, 60);
        }

     
    }
}
